﻿using db_manage.dll.common;
using db_manage.dll.manage;
using db_manage.model;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Windows.Forms;

namespace db_manage.page
{
    public partial class form_exec : Form
    {
        private static form_db_info form_db_info { get => manage.from_get<form_db_info>(); }
        private db_config_exec db_config_exec
        {
            get
            {
                return manage.db_manage_config?.db_config_exec;
            }
        }

        public form_exec()
        {
            InitializeComponent();
            config_get();
        }

        private void config_get()
        {
            if (db_config_exec == null)
            {
                manage.db_manage_config.db_config_exec = new model.db_config_exec();
            }
            tb_sql_dir.Text = db_config_exec.sql_dir ?? "db_sql";
            if (manage.db_manage_config.task_num < 1)
            {
                manage.db_manage_config.task_num = 1;
            }
            tb_ver.Text = db_config_exec.ver_range;
            cb_repeat.Checked = db_config_exec.check_repeat ?? false;
            cb_lose.Checked = db_config_exec.check_lose ?? false;
            cb_ingorefail.Checked = db_config_exec.ingore_fail ?? false;
            cb_lastnum.Checked = db_config_exec.begin_last_successnum ?? false;
        }

        private void config_set()
        {
            if (db_config_exec == null)
            {
                manage.db_manage_config.db_config_exec = new model.db_config_exec();
            }
            db_config_exec.sql_dir = tb_sql_dir.Text;
            if (manage.db_manage_config.task_num < 1)
            {
                manage.db_manage_config.task_num = 1;
            }
            db_config_exec.ver_range = tb_ver.Text;
            db_config_exec.check_repeat = cb_repeat.Checked;
            db_config_exec.check_lose = cb_lose.Checked;
            db_config_exec.ingore_fail = cb_ingorefail.Checked;
            db_config_exec.begin_last_successnum = cb_lastnum.Checked;
        }

        /// <summary>
        /// 读取脚本文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bt_read_Click(object sender, EventArgs e)
        {
            //展示对话框
            ofd_read.ShowDialog();

            ////获得在打开的对话框中选中文件的路径
            string path = ofd_read.FileName;

            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            tb_read.Text = helper_io.ReadAllText(path);
        }

        private void sql_exec(List<sql_fileinfo> sql_list)
        {
            form_db_info.ShowAndBringToFront();
            var res = manage.sql_exec(sql_list);

            if (!string.IsNullOrEmpty(res))
            {
                MessageBox.Show(res);
            }
        }

        /// <summary>
        /// 执行脚本
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bt_exec_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tb_read.Text))
            {
                MessageBox.Show("脚本不能为空");
                return;
            }
            sql_exec(new List<sql_fileinfo>() {
               new sql_fileinfo() {
               vernum=-1,
               sql=tb_read.Text
               }
            });
        }

        /// <summary>
        /// 选择脚本目录
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bt_dir_Click(object sender, EventArgs e)
        {
            //展示对话框
            fbd_sql.ShowDialog();

            ////获得在打开的对话框中选中的路径
            string path = fbd_sql.SelectedPath;

            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            tb_sql_dir.Text = path;
            config_set();
        }

        /// <summary>
        /// 执行目录中脚本
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bt_exec_dir_Click(object sender, EventArgs e)
        {
            //查找脚本文件
            var path = string.IsNullOrEmpty(db_config_exec.sql_dir) ? "db_sql" : db_config_exec.sql_dir;
            if (!Directory.Exists(path))
            {
                MessageBox.Show($"脚本文件路径{path}不存在");
                return;
            }
            var files = Directory.GetFiles(path, "*.sql", SearchOption.AllDirectories);
            if (files == null || !files.Any())
            {
                MessageBox.Show("不存在脚本文件");
                return;
            }
            var file_list = new List<sql_fileinfo>();
            int? startNum = null;//开始版本
            int? endNum = null;//结束版本
            if (!string.IsNullOrEmpty(db_config_exec.ver_range))
            {
                var startendStrs = db_config_exec.ver_range.Split("-".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                if (startendStrs != null && startendStrs.Any())
                {
                    startNum = Convert.ToInt32(startendStrs[0]);
                    if (startendStrs.Length > 1)
                    {
                        endNum = Convert.ToInt32(startendStrs[1]);
                    }
                }
            }
            foreach (var item in files)
            {
                var fileName = Path.GetFileName(item);
                if (!fileName.Contains("_"))
                {
                    continue;
                }
                var fileNames = fileName.Split("_".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                if (!int.TryParse(fileNames[0], out int num))//规定文件名第一个是版本号
                {
                    MessageBox.Show(fileNames[0] + "版本号错误");
                    return;
                }
                if (startNum != null && num < startNum)
                {
                    continue;
                }
                if (endNum != null && num > endNum)
                {
                    continue;
                }
                //校验版本重复
                if (file_list.Any(x => x.vernum == num) && (db_config_exec.check_repeat ?? false))
                {
                    MessageBox.Show($"版本号{num}存在重复脚本文件");
                    return;
                }

                var sqlStr = helper_io.ReadAllText(item);
                file_list.Add(new sql_fileinfo()
                {
                    filename = fileName,
                    path = item,
                    vernum = num,
                    sql = sqlStr
                });
            }
            if (file_list != null && !file_list.Any())
            {
                MessageBox.Show("不存在符合条件脚本文件");
                return;
            }

            file_list = file_list.OrderBy(x => x.vernum).ToList();
            //校验版本缺失
            if (db_config_exec.check_lose ?? false)
            {
                var fileVerNum = file_list.FirstOrDefault().vernum;
                foreach (var item in file_list)
                {
                    if (fileVerNum != item.vernum)
                    {
                        MessageBox.Show($"版本号{fileVerNum}缺失脚本文件");
                        return;
                    }
                    fileVerNum++;
                }
            }

            sql_exec(file_list);
        }

        /// <summary>
        /// 保存配置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bt_save_Click(object sender, EventArgs e)
        {
            config_set();
            manage.db_manage_config = manage.db_manage_config;
        }

        /// <summary>
        /// 数据更新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void data_update(object sender, EventArgs e)
        {
            config_set();
        }
    }
}
